/**
 * WechatBot
 *  - https://github.com/gengchen528/wechatBot
 */
const { WechatyBuilder } = require('wechaty');
const schedule = require('./schedule/index');
const config = require('./config/index');
const untils = require('./utils/index');
const superagent = require('./superagent/index');
const fs = require('fs');
const path = require('path');
const jpApi = require('./JpApi.js');
const { FileBox } = require('file-box')


//识别二维码库
const Jimp = require('jimp');
const QrCode = require('qrcode-reader');
const jsQR = require('jsqr');
// 延时函数，防止检测出类似机器人行为操作
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

// 二维码生成
function onScan(qrcode, status) {
  require('qrcode-terminal').generate(qrcode); // 在console端显示二维码
  const qrcodeImageUrl = [
    'https://api.qrserver.com/v1/create-qr-code/?data=',
    encodeURIComponent(qrcode),
  ].join('');

  console.log(qrcodeImageUrl);
}

// 登录
async function onLogin(user) {
  console.log(`雷子的小助理${user}登录了`);
  const date = new Date()
  console.log(`当前容器时间:${date}`);
  if (config.AUTOREPLY) {
    console.log(`已开启机器人自动聊天模式`);
  }
  // 登陆后创建定时任务
  await initDay();
  //登录我的账号
  await jpApi.login()
}

// 登出
function onLogout(user) {
  console.log(`小助手${user} 已经登出`);
}


/**
 * 解析命令
 */
function parseCommand(content) {
  // 定义正则表达式，匹配以#开头，后跟任意字符（登录码），然后是一个或多个数字
  const regex = /#(.+?)\s+(\d+)/;
  const match = regex.exec(content);
  if (match) {
    const cmd = match[1]; // 提取登录码
    const number = match[2]; // 提取数字
    return { cmd, number };
  } else {
    return null; // 如果未匹配到，则返回 null
  }
}

// 监听对话
async function onMessage(msg) {
  const contact = msg.talker(); // 发消息人
  const content = msg.text().trim(); // 消息内容
  const room = msg.room(); // 是否是群消息
  const alias = await contact.alias() || await contact.name(); // 发消息人备注
  const isText = msg.type() === bot.Message.Type.Text;
  const isImage = msg.type() === bot.Message.Type.Image;
  if (msg.self()) {
    return;
  }

  console.log(`msg.type()：=` + msg.type());

  //群消息
  if (room && isText) {
    // 如果是群消息 目前只处理文字消息
    const topic = await room.topic();
    console.log(`群名: ${topic} 发消息人: ${await contact.name()} 内容: ${content}`);

    const fromName = await contact.name()
    console.log(fromName);
    console.log(config.GROUPNAME.indexOf(topic));
    console.log(config.WHITELIST.indexOf(fromName));

    if (config.GROUPNAME.indexOf(topic) > -1 && config.WHITELIST.indexOf(fromName) > -1) {
      if (isText) {
        handleTextMessage(contact, room, content)
      } else if (isImage) {
        handleImageMessage(msg)
      }
    } else {
      console.log(`不满足条件暂不回复`);
    }

  } else {
    console.log(`发消息人: ${alias} 消息内容: ${content}`);
    if (config.WHITELIST.indexOf(alias) > -1) {
      if (isText) {
        handleTextMessage(contact, room, content)
      } else if (isImage) {
        handleImageMessage(msg)
      }
    } else {
      console.log(`不是主人不回复哒`);
    }
  }
}


/**
 * 处理图片消息
 */
async function handleImageMessage(msg) {
  console.log('收到图片消息');
  const fileBox = await msg.toFileBox();
  const dirPath = path.join(__dirname, 'received-images');

  // 检查目录是否存在，如果不存在则创建目录
  if (!fs.existsSync(dirPath)) {
    fs.mkdirSync(dirPath, { recursive: true });
  }

  const filePath = path.join(dirPath, fileBox.name);
  await fileBox.toFile(filePath);
  console.log(`图片保存到 ${filePath}`);

  Jimp.read(filePath)
  .then(image => {
    // 减少图像噪声
    image
      .resize(500, Jimp.AUTO)  // 调整图像宽度为500像素，高度按比例缩放
      .contrast(1)  // 增加对比度
      .greyscale()  // 转换为灰度图像
      .normalize()  // 归一化
      .quality(100) // 设置图像质量
      .getBuffer(Jimp.MIME_PNG, (err, buffer) => {
        if (err) {
          console.error('图片处理失败', err);
          return;
        }

        const { data, width, height } = image.bitmap;
        const code = jsQR(data, width, height);

        if (code) {
          console.log('二维码内容:', code.data);
        } else {
          console.log('未能识别到二维码');
        }
      });
  })
  .catch(err => {
    console.error('图片处理失败', err);
  });

}



/**
 * 处理文字信息
 */
async function handleTextMessage(contact, room, content) {
  if (content.substr(0, 1) == '#') {
    const jsonCommand = parseCommand(content)
    console.log(`收到命令：${jsonCommand.cmd}`);
    let res;
    switch (jsonCommand.cmd) {
      case "登录吗":
      case "登录码": {
        if (isValidString(jsonCommand.number)) {
          let cinemaCode;
          let deviceNo;
          if (jsonCommand.number.length == 10) {
            cinemaCode = jsonCommand.number.substr(0, jsonCommand.number.length - 2)
            deviceNo = jsonCommand.number.substr(jsonCommand.number.length - 2, jsonCommand.number.length)
          } else {
            cinemaCode = jsonCommand.number
            deviceNo = "01"
          }
          //获取影院信息
          let obj = await jpApi.getTicketInfo(cinemaCode, deviceNo)
          console.log(`clienId${obj.id}`);
          //生成Login字符串
          let qrLogin = await jpApi.getLoginQrCode(obj.id);
          //发送二维码
          sendQrCode(contact, room, qrLogin)
        }
        return
        break;
      }
      case "注销吗":
      case "注销码": {
        if (isValidString(jsonCommand.number)) {
          let cinemaCode;
          let deviceNo;
          if (jsonCommand.number.length == 10) {
            cinemaCode = jsonCommand.number.substr(0, jsonCommand.number.length - 2)
            deviceNo = jsonCommand.number.substr(jsonCommand.number.length - 2, jsonCommand.number.length)
          } else {
            cinemaCode = jsonCommand.number
            deviceNo = "01"
          }
          //获取影院信息
          let obj = await jpApi.getTicketInfo(cinemaCode, deviceNo)
          console.log(`clienId${obj.id}`);
          //生成Login字符串
          let qrLogin = await jpApi.getLogoutQrCode(obj.id);
          //发送二维码,
          sendQrCode(contact, room, qrLogin)
        }
        return
        break
      }
      case "版本号":
      case "版本信息":
      case "版本": {
        if (isValidString(jsonCommand.number)) {
          let cinemaCode;
          let deviceNo;
          if (jsonCommand.number.length == 10) {
            cinemaCode = jsonCommand.number.substr(0, jsonCommand.number.length - 2)
            deviceNo = jsonCommand.number.substr(jsonCommand.number.length - 2, jsonCommand.number.length)
          } else {
            cinemaCode = jsonCommand.number
            deviceNo = "01"
          }
          //获取影院信息
          let obj = await jpApi.getTicketInfo(cinemaCode, deviceNo)
          console.log(`clienId${obj.id}`);
          //生成Login字符串
          res = await jpApi.getTicketVersion(cinemaCode, obj.id);
        }
        break
      }
      case "查看":
      case "信息":
      case "查询": {

        if (isValidString(jsonCommand.number)) {
          let cinemaCode;
          let deviceNo;
          if (jsonCommand.number.length == 10) {
            cinemaCode = jsonCommand.number.substr(0, jsonCommand.number.length - 2)
            deviceNo = jsonCommand.number.substr(jsonCommand.number.length - 2, jsonCommand.number.length)
          } else {
            cinemaCode = jsonCommand.number
            deviceNo = "01"
          }
          //获取影院信息
          let obj = await jpApi.getTicketInfo(cinemaCode, deviceNo)

          res = `影院名称：${obj.cinemaName}\n设备名称：${obj.name}\n是否在线：${obj.online}\n最后在线时间：${obj.lastOnlineTime}`

        }
        break
      }
      case "音量配置":
      case "开检配置":
      case "基础配置":
      case "配置信息":
      case "配置": {
        if (isValidString(jsonCommand.number)) {
          let cinemaCode;
          let deviceNo;
          if (jsonCommand.number.length == 10) {
            cinemaCode = jsonCommand.number.substr(0, jsonCommand.number.length - 2)
            deviceNo = jsonCommand.number.substr(jsonCommand.number.length - 2, jsonCommand.number.length)
          } else {
            cinemaCode = jsonCommand.number
            deviceNo = "01"
          }


          //获取影院信息
          let obj = await jpApi.getTicketInfo(cinemaCode, deviceNo)
          console.log(`clienId${obj.id}`);
          //获取影院信息
          res = await jpApi.getTicketConfig(obj.id)
        }

        break
      }
      case "验票平台":
      case "检票方式": {
        if (isValidString(jsonCommand.number)) {
          let cinemaCode;
          let deviceNo;
          if (jsonCommand.number.length == 10) {
            cinemaCode = jsonCommand.number.substr(0, jsonCommand.number.length - 2)
            deviceNo = jsonCommand.number.substr(jsonCommand.number.length - 2, jsonCommand.number.length)
          } else {
            cinemaCode = jsonCommand.number
            deviceNo = "01"
          }
          //获取影院信息
          let obj = await jpApi.getTicketInfo(cinemaCode, deviceNo)
          console.log(`cinemaId${obj.cinemaId}`);
          //获取影院信息
          res = await jpApi.getCheckConfig(obj.cinemaId)
        }
        break
      }
      case "版本号": {
        res = "v1.1.0";
        break;
      }
      case "绑定影院":
      case "关联影院":
      case "绑定":
      case "关联": {
        if (isValidString(jsonCommand.number)) {
          let cinemaCode;
          let deviceNo;
          if (jsonCommand.number.length == 10) {
            cinemaCode = jsonCommand.number.substr(0, jsonCommand.number.length - 2)
            deviceNo = jsonCommand.number.substr(jsonCommand.number.length - 2, jsonCommand.number.length)
          } else {
            cinemaCode = jsonCommand.number
            deviceNo = "01"
          }
          //获取影院信息
          let [id, name] = await jpApi.getCinemas(cinemaCode)//获取影院的id
          //获取影院信息
          let message = await jpApi.getAdminInfo(id, name)

          if (message == "SUCCESS") {
            res = `绑定影院【${name}】成功`
          } else {
            res = `绑定影院【${name}】失败,原因【${message}】`
          }

        }
        break
      }
      case "二维码":
      case "转二维码":{

      }
      default: {
        res = '未识别的命令'; // 默认情况下，赋值一个提示信息
        break;
      }

    }
    await delay(1000);
    if (room) {
      await room.say(res);
    } else {
      await contact.say(res);
    }
  }
}


async function sendQrCode(contact, room, qrContent) {
  try {
    const savedFilePath = await jpApi.generateQRCode(qrContent);
    console.log('Image saved to2222', savedFilePath);

    const fileBox2 = FileBox.fromFile(savedFilePath);

    if (room) {
      await room.say(fileBox2);
    } else {
      await contact.say(fileBox2);
    }
  } catch (error) {
    console.error('Error saving image file222', error);
  }
}


function isValidString(str) {
  // 判断是否全部是数字
  const isAllDigits = /^\d+$/.test(str);

  // 判断字符串长度是否为8或10
  const isLengthValid = str.length === 8 || str.length === 10;

  // 返回验证结果
  return isAllDigits && isLengthValid;
}



// 创建微信盯人任务
async function initDay() {
  console.log(`已经设定每日说任务`);

  schedule.setSchedule(config.SENDDATE, async () => {
    console.log('你的贴心小助理开始工作啦！');
    let logMsg;
    let contact =
      (await bot.Contact.find({ name: config.NICKNAME })) ||
      (await bot.Contact.find({ alias: config.NAME })); // 获取你要发送的联系人


    // let one = await superagent.getOne(); //获取每日一句
    // let weather = await superagent.getTXweather(); //获取天气信息
    // let today = await untils.formatDate(new Date()); //获取今天的日期
    // let memorialDay = untils.getDay(config.MEMORIAL_DAY); //获取纪念日天数
    // let sweetWord = await superagent.getSweetWord();

    // // 你可以修改下面的 str 来自定义每日说的内容和格式
    // // PS: 如果需要插入 emoji(表情), 可访问 "https://getemoji.com/" 复制插入
    // let str = `${today}\n我们在一起的第${memorialDay}天\n\n元气满满的一天开始啦,要开心噢^_^\n\n今日天气\n${weather.weatherTips}\n${weather.todayWeather}\n每日一句:\n${one}\n\n每日土味情话：\n${sweetWord}\n\n————————最爱你的我`;
    try {
      logMsg = "你好";
      await delay(2000);
      await contact.say(logMsg); // 发送消息
    } catch (e) {
      logMsg = e.message;
    }
    console.log(logMsg);
  });

}


/**
 * 初始化喝水机器人
 */
async function drinkWaterTask() {


}



const bot = WechatyBuilder.build({
  name: 'WechatEveryDay',
  puppet: 'wechaty-puppet-wechat4u', // 如果有token，记得更换对应的puppet
})

bot.on('scan', onScan);
bot.on('login', onLogin);
bot.on('logout', onLogout);
bot.on('message', onMessage);

bot
  .start()
  .then(() => console.log('开始登陆微信'))
  .catch((e) => console.error(e));
